using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using SharpMud.MudLib.Common.Resourcing;

namespace SharpMud.MudLib.Common.Environment.Persistance
{
    [XmlRoot("RoomReference")]
    public class RoomReference
    {
        private string _RoomGuidString;
        private string _RoomUriString;
        private IRoom _Room;

        public RoomReference()
        {
            _RoomGuidString = "";
            _RoomUriString = "";
        }
        public RoomReference(Guid roomGuid)
        {
            if (roomGuid == null)
                throw new ArgumentNullException("roomGuid");
            _RoomGuidString = roomGuid.ToString();
            _RoomUriString = "";
        }
        public RoomReference(Uri roomUri)
        {
            if (roomUri == null)
                throw new ArgumentNullException("roomUri");
            _RoomGuidString = "";
            _RoomUriString = roomUri.ToString();
        }
        public RoomReference(Guid roomGuid, Uri roomUri)
        {
            if (roomGuid == null)
                throw new ArgumentNullException("roomGuid");
            if (roomUri == null)
                throw new ArgumentNullException("roomUri");
            _RoomGuidString = roomGuid.ToString();
            _RoomUriString = roomUri.ToString();
        }
        public RoomReference(IRoom room)
        {
            if (room is IHasInstanceGuid)
                this._RoomGuidString = ((IHasInstanceGuid)room).ID.ToString();
            if (room is IHasInstanceUri)
                this._RoomUriString = ((IHasInstanceUri)room).ID.ToString();
            _Room = room;
        }

        [XmlIgnore()]
        public IRoom Room
        {
            get
            {
                return _Room;
            }
        }

        [XmlAttribute("RoomGuid")]
        public string RoomGuidString
        {
            get
            {
                return _RoomGuidString;
            }
            set
            {
                _RoomGuidString = value;
            }
        }
        [XmlAttribute("RoomUri")]
        public string RoomUriString
        {
            get
            {
                return _RoomUriString;
            }
            set
            {
                _RoomUriString = value;
            }
        }
        [XmlIgnore()]
        public Guid RoomGuid
        {
            get
            {
                if (_RoomGuidString == String.Empty)
                    return Guid.Empty;
                return new Guid(_RoomGuidString);
            }
        }
        [XmlIgnore()]
        public Uri RoomUri
        {
            get
            {
                if (_RoomUriString == String.Empty)
                    return null;
                return new Uri(_RoomUriString);
            }
        }
        
        public IRoom FindInEnvironment(IEnvironmentManager environmentManager)
        {
            IRoom result=null;
            if (this.RoomUri != null)
            {
                result = (environmentManager.GetResource(this.RoomUri) as IRoom);
            }
            if (result != null)
                return result;
            if (this.RoomGuid != null)
            {
                result = (environmentManager.GetResource(this.RoomGuid) as IRoom);
            }
            return result;
        }

        public static RoomReference FromRoom(IRoom room)
        {
            RoomReference rr = new RoomReference();
            if (room is IHasInstanceGuid)
            {
                if (!((room as IHasInstanceGuid).ID == null))
                {
                    rr._RoomGuidString = (room as IHasInstanceGuid).ID.ToString();
                }
            }
            if (room is IHasInstanceUri)
            {
                if (!((room as IHasInstanceUri).ID == null))
                {
                    rr._RoomUriString = (room as IHasInstanceUri).ID.ToString();
                }
            }
            if ((rr._RoomGuidString == null || rr._RoomGuidString == String.Empty)
                && (rr._RoomUriString == null || rr._RoomUriString == String.Empty))
                throw new InvalidOperationException("The IRoom instance is not in a state where it can be uniquely identified.");
            return rr;
        }
    }
}
